package jtacck.labmedicine;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import jvm.jtacck.db.records.CheckListPair;
import jvm.jtacck.db.records.ClientSite;
import jvm.jtacck.db.records.Hospital;
import jvm.jtacck.db.records.ShippingInformation;

public class Cache {
    
    public enum ChecklistState {
        START,
        END,
        SITE,
        SHIPPING,
        ROUTE,
        NULL;
    }
    
    private CheckListPair checkLists;
//    private ChecklistState state;
    private RouteData data;
    private Hospital currentHosp;
    private ClientSite currentSite;
    private Map<ClientSite, Set<ShippingInformation>> collected;

    public Cache() {
        data = new RouteData();
        checkLists = new CheckListPair(new ArrayList<String>(),
                new ArrayList<String>());
//        state = ChecklistState.START;
        currentSite = null;
        currentHosp = null;
        collected = new HashMap<ClientSite, Set<ShippingInformation>>();
    }
    
    protected synchronized String[] startRoute() {
//        state = ChecklistState.START;
        return checkLists.startingList.toArray(new String[0]);
    }
    
    protected synchronized String[] arriveHosp(Hospital hosp) {
//        state = ChecklistState.ROUTE;
        currentHosp = hosp;
        List<ClientSite> info = data.getSites(currentHosp);
        String[] answer = new String[info.size()];
        for(int i = 0; i < info.size(); i++)
            answer[i] = info.get(i).name;
        return answer;
    }
    
    private boolean siteDone(ClientSite site) {
        for(ShippingInformation info : data.getPackages(site))
            if(info.status.status_id < 2 && !collected.containsValue(info))
                return false;
        return true;
    }
    
    
    protected synchronized List<Boolean> isChecked(ChecklistState state) {
        List<Boolean> answer = new ArrayList<Boolean>();
        switch(state) {
        case START: return null;
        case END: return null;
        case SITE: return null;
        case SHIPPING: 
            for(int i = 0; i < data.getPackages(currentSite).size(); i++)
                answer.add(data.getPackages(currentSite).get(i).status.status_id >= 2 || collected.containsKey(currentSite) && collected.get(currentSite).contains(data.getPackages(currentSite).get(i)));
            break;
        case ROUTE: for(int i = 0; i < data.getSites(currentHosp).size(); i++)
            answer.add(siteDone(data.getSites(currentHosp).get(i)));
            break;
        }
        return answer;
    }
    
    protected synchronized void collect(String barcode) {
        int packageID = 0;
        while(packageID <= data.getPackages(currentSite).size())
            if(barcode.equals(data.getPackages(currentSite).get(packageID).specimen.barcode))
                break;
            else
                packageID++;
        if(collected.containsKey(currentSite)) {
            Set<ShippingInformation> info = collected.get(currentSite);
            info.add(data.getPackages(currentSite).get(packageID));
            collected.put(currentSite, info);
        }else {
            Set<ShippingInformation> info = new HashSet<ShippingInformation>();
            info.add(data.getPackages(currentSite).get(packageID));
            collected.put(currentSite, info);
        }
            
    }
    
    protected synchronized String[] endRoute() {
//        state = ChecklistState.END;
        return checkLists.endingList.toArray(new String[0]);
    }
    
    protected ChecklistState strToEnum(String string) {
        if(string.equals("START"))
            return ChecklistState.START;
        else if(string.equals("END"))
            return ChecklistState.END;
        else if(string.equals("ROUTE"))
            return ChecklistState.ROUTE;
        else if(string.equals("SITE"))
            return ChecklistState.SITE;
        else if(string.equals("SHIPPING"))
            return ChecklistState.SHIPPING;
        else
            return null;
    }
    
    protected synchronized String[] arriveSite(ClientSite site) {
        currentSite = site;
//        state = ChecklistState.SITE;
        return currentSite.instructions.toArray(new String[0]);
    }
    
    protected synchronized String[] getPackages() {
//        state = ChecklistState.SHIPPING;
        List<String> answer = new ArrayList<String>();
        for(ShippingInformation info : data.getPackages(currentSite))
            answer.add(info.specimen.description);
        return answer.toArray(new String[0]);
    }
    
    
    protected synchronized void setStartEndChecklists(CheckListPair lists) {
        checkLists = lists;
    }
    
    protected RouteData getRouteData() {
        return data;
    }
    
    protected ShippingInformation getPackageById(int id) {
        return data.getPackages(currentSite).get(id);
    }

}